package cn.fuxi2022.commons.redis.utils;

import org.apache.commons.lang.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.support.atomic.RedisAtomicLong;
import org.springframework.stereotype.Component;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * 实现订单流水号，要求订单编号的尾号从上往下依次递增，而不是随机生成
 */
@Component
public class SequenceUtils {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    private Integer orderMixSize = 3;

    // 2.把时间转成Long类型
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    SimpleDateFormat sdf2 = new SimpleDateFormat("yyyyMMdd");

    /**
     * 生成订单流水号方法
     * @return 生成的订单流水号
     */
    public String getOrderId() {
        // 1.时间
        String date = sdf2.format(new Date());

        // 2.四位随机数
        String random = RandomStringUtils.random(4, false, true);

        // 3.流水号
        String orderSequence = getOrderSequence();

        return date + random + orderSequence;

    }

    public String getOrderSequence() {

        // 1.获取订单的流水号
        Long orderSeq = getModelSequence("helper:order:sequence");
//        Long orderSeq = getModelSequence("shop:userr:sequence");

        StringBuffer buffer = new StringBuffer(orderSeq.toString());

        if (buffer.length() >= orderMixSize) { // 流水号最小是3位
            return buffer.toString();
        }

        int end = buffer.length();
        if (buffer.length() < orderMixSize) {
            for (int i = 0; i < orderMixSize - end; i++) {
                buffer.insert(0, "0");
            }
        }
        return buffer.toString();
    }

    /**
     * @param model 模块的流水号
     * @return
     */
    public Long getModelSequence(String model) {

        // 1.创建一个原子性的对象，操作long类型 ,如果key不存在会自动创建 (stock-index)
        RedisAtomicLong redisAtomicLong = new RedisAtomicLong(model, stringRedisTemplate.getConnectionFactory());

        // 2.自增
        long log = redisAtomicLong.incrementAndGet();

        if (log == 1) { // 第一次自增的时候设置超时间
            // 1.获取当天的最后时间(23:59:59)
            String currEndDate = LocalDate.now().toString() + " 23:59:59";

            try {
                // 3、获取当天最后的时间的long类型
                long currEndDateLong = sdf.parse(currEndDate).getTime();

                // 4.获取当前时间
                long currDateLong = System.currentTimeMillis(); // long类型的时间是毫秒

                // 5、计算时间差(Long类型)
                Long expTime = currEndDateLong - currDateLong;

                // 6、设置过期时间
                redisAtomicLong.expire(expTime / 1000, TimeUnit.SECONDS);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        return log;
    }
}